/*
 * Settings.java
 *
 * Created on 25 ��� 2005 �., 2:50
 *
 * To change this template, choose Tools | Options and locate the template under
 * the Source Creation and Management node. Right-click the template and choose
 * Open. You can then make changes to the template in the Source Editor.
 */

package ua.org.sovic.common;

import java.io.File;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;

import ua.org.sovic.xml.DOMSerializer;

/**
 *
 * @author SoVic
 */
public class Settings {
    @SuppressWarnings("rawtypes")
	private HashMap fHashMap;
    private String project = "";
    private boolean loading = false;
      
    /** Creates a new instance of Settings */
    @SuppressWarnings("rawtypes")
	protected Settings() {
        fHashMap = new HashMap();
        project = "default";
    }
    
    protected void setProjectName(String project) {
        this.project = project;
    }
    @SuppressWarnings({ "rawtypes", "unchecked" })
	private void putHash(HashMap map, String key, Object value) {
        int sPos = key.indexOf(".");
        if (sPos != -1) {
            String _key = key.substring(0, sPos);
            if (map.get(_key) == null) { 
                map.put(_key, new HashMap());
            }
            putHash((HashMap) map.get(_key), key.substring(sPos+1), value);
        } else {
            map.put(key,  value);
        }
    }
    @SuppressWarnings("rawtypes")
	private Object getHash(HashMap map, String key) {
        int sPos = key.indexOf(".");
        Object _value = null;
        if (sPos != -1) {
            String _key = key.substring(0, sPos);
            HashMap _map = (HashMap) map.get(_key);
            if (_map == null) {
                return null;
            }
            _value = getHash(_map, key.substring(sPos+1));
        } else {
            _value = map.get(key);
        }
        return _value;
    }
    
    protected Object getKey(String key) {
        return getHash(fHashMap, key);
    }
    protected Object getKey(String key, Object deflt) {
        Object obj = getHash(fHashMap, key);
        if (obj == null) {
            return deflt;
        } else {
            return obj;
        }
    }
    protected int getIntKey(String key, int deflt) {
        Object obj = getHash(fHashMap, key);
        if (obj == null) {
            return deflt;
        } else {
            return new Integer((String) obj).intValue();
        }
    }
    protected void putKey(String key, Object data) {
        //prevent null values. Hasmap allow them
        if (data == null) {
            throw new IllegalArgumentException();
        } else {
            putHash(fHashMap, key, data);
        }
    }

    protected void clearHash() {
        fHashMap.clear();
    }
    @SuppressWarnings("rawtypes")
	protected boolean save(File file) throws Exception {
        // Create new DOM tree
        DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
        Document doc = docBuilder.parse(file);
        Element root = doc.getDocumentElement();
        root.setAttribute("project", project);            
        Set set = ((HashMap) getKey(project)).keySet();
        if (set != null) {
            for (Iterator iterator = set.iterator(); iterator.hasNext(); ) {
                Element propertiesElement = doc.createElement("properties");
                String section = iterator.next().toString();
                propertiesElement.setAttribute("section", section);
                root.appendChild(propertiesElement);
                // Set proterty
                Set setP = ((HashMap) getKey(project + "." + section)).keySet();
                if (setP != null) {
                    for (Iterator iteratorP = setP.iterator(); iteratorP.hasNext(); ) {
                        String key = iteratorP.next().toString();
                        Element propertyElement = doc.createElement("property");
                        propertyElement.setAttribute("key", key);
                        Text nameText = doc.createTextNode(getKey(project + "." + section + "." + key).toString());
                        propertyElement.appendChild((Node) nameText);
                        propertiesElement.appendChild(propertyElement);
                    }
                }
            }
        }    
        // Serialize DOM tree into file
        DOMSerializer serializer = new DOMSerializer();
        serializer.serialize(doc, file);
        return true;
    }
    protected boolean load(File file) throws Exception {
        String section = "";
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document doc = builder.parse(file);
        if (doc == null) {
            throw new NullPointerException();
        }
        // Get project name
        NamedNodeMap projects = doc.getDocumentElement().getAttributes();
        if (projects != null) {
            Node n = projects.getNamedItem("project");
            if (n != null) {
                project = n.getNodeValue();
                
            }
        }
        NodeList propertiesNL = doc.getDocumentElement().getChildNodes();
        if (propertiesNL != null) {
            for (int i = 0; (i < propertiesNL.getLength()); i++) {
                if (propertiesNL.item(i).getNodeName().equals("properties")) {
                    // Get sections
                    NamedNodeMap sections = propertiesNL.item(i).getAttributes();
                    if (sections != null) {
                        Node n = sections.getNamedItem("section");
                        if (n != null) {
                            section = project + "." + n.getNodeValue();
                        }
                    }
                    NodeList propertyList = propertiesNL.item(i).getChildNodes();
                    for (int j = 0; j < propertyList.getLength(); j++) {
                        NamedNodeMap attributes = propertyList.item(j).getAttributes();
                        if (attributes != null) {
                            Node n = attributes.getNamedItem("key");
                            NodeList childs = propertyList.item(j).getChildNodes();
                            if (childs != null) {
                                for (int k = 0; k < childs.getLength(); k++) {
                                    if (childs.item(k).getNodeType() == Node.TEXT_NODE) {
                                        putKey(section + "." + n.getNodeValue(), childs.item(k).getNodeValue());
                                    }
                                }
                            }
                        }
                    }
                }
            }
            loading = true;
            return true;
        } else {
            loading = false;
            return false;
        }
    }
    protected boolean getLoading() {
        return loading;
    }    
}
